#ifndef BEHEAVIOR_H
#define BEHEAVIOR_H

#include "common.h"
#include "tempprocess.h"
#include "zoomlabel.h"
#include "mainwindow.h"

#include "imgshow.h"

void saveStatus(ZoomLabel* imgContainer,TempProcess* tempObj,QWidget* parent)
{
    //保存状态
    //保存当前状态
    MainWindow *w = (MainWindow*)parent;
    if(w->env->getEnvironmentLists()->size() == 0) return;
    //20240808
    w->envInfo->centerPos = imgContainer->getCenterPos();
    w->envInfo->rotateFactor = imgContainer->getRotateFactor();
    //
    w->envInfo->realPicSize = imgContainer->getRealPicSize();
    w->envInfo->origPicSize = imgContainer->getOrigPicSize();
    w->envInfo->scaleFactor = imgContainer->getScaleFactor();
    w->envInfo->pmap = imgContainer->getPmap();
    *(w->envInfo->tmp) = imgContainer->getTemp();
    *(w->envInfo->regionTmp) = *(imgContainer->regionTmp);
    w->envInfo->pic = imgContainer->getPic();
    w->envInfo->imgOffset = imgContainer->getPicOffset();
    w->envInfo->polyOffset = imgContainer->getPolyOffset();
    w->envInfo->isCompleteEdit = imgContainer->getEditStatus();
    w->envInfo->mode = imgContainer->getMode();
    *(w->envInfo->tempPt) = imgContainer->tempPt;
    w->envInfo->poly = imgContainer->poly;
    w->envInfo->tMax = tempObj->getTmpDiff().first;
    w->envInfo->tMin = tempObj->getTmpDiff().second;
    w->envInfo->currImg = *(imgContainer->currImg);
    w->currImg = w->envInfo->currImg;
    w->env->updateEnvironment(w->selectedIndex,(w->envInfo));
}

void addFile(QListWidget* listWidget, QWidget* parent) {
    QStringList filePath = QFileDialog::getOpenFileNames(parent, "Open File", "", "Text Files (*.txt)");
    if(!filePath.isEmpty())
    {
        for(auto file = filePath.begin();file!=filePath.end();file++)
        {
            QListWidgetItem *item = new QListWidgetItem(*file,listWidget);
            listWidget->addItem(item);
        }

    }
}

void deleteFile(QListWidget* listWidget, ZoomLabel* imgContainer,TempProcess* tempObj,QWidget* parent)
{
    MainWindow *w = (MainWindow*)parent;
    QListWidgetItem *item = listWidget->currentItem();
    int index = listWidget->currentRow();
    saveStatus(imgContainer,tempObj,parent);
    EnvironmentInfo *info = new EnvironmentInfo();
    info->operator=(w->selectEnvironment(w->selectedIndex));
    if(index != w->selectedIndex)
    {
            w->env->delEnvironment(index);
            //delete listWidget->takeItem(listWidget->row(item));
            listWidget->takeItem(listWidget->row(item));
            if(index < w->selectedIndex)
            {
                w->selectedIndex = w->selectedIndex - 1;
                w->envInfo = info;
            }
            else
            {
                w->envInfo = info;
            }

    }
    else
    {
        QMessageBox::warning(parent,"完成","当前图片处于工作状态，无法删除");
    }
    imgContainer->refresh();
}

void showTempImg(QListWidget* listWidget, ZoomLabel* imgContainer, QWidget* parent, TempProcess* tempObj)
{
    MainWindow *w = (MainWindow*)parent;
    QListWidgetItem *item = listWidget->currentItem();
    if(item)
    {
        int index = listWidget->currentRow();
        if(w->env->containsEnvironment(index))
        {
            //保存当前状态
            saveStatus(imgContainer,tempObj,parent);

            w->selectedIndex = index;
            w->envInfo->operator=(w->env->selectEnvironment(w->selectedIndex));


            //设置新属性，刷新
            //20240808
            imgContainer->setStatus(0);
            imgContainer->setCenterPos(w->envInfo->centerPos);
            imgContainer->setRotateFactor(w->envInfo->rotateFactor);
            //
            imgContainer->setRealPicSize(w->envInfo->picSize);
            imgContainer->setOrigPicSize(w->envInfo->origPicSize);
            imgContainer->setScaleFactor(w->envInfo->scaleFactor);
            imgContainer->setTemp(*(w->envInfo->tmp));
            imgContainer->setPicOffset(w->envInfo->imgOffset);
            imgContainer->setPolyOffset(w->envInfo->polyOffset);
            imgContainer->setEditStatus(w->envInfo->isCompleteEdit);
            imgContainer->setMode(w->envInfo->mode);
            imgContainer->setPic(w->envInfo->pic);
            imgContainer->tempPt = *(w->envInfo->tempPt);
            imgContainer->poly = w->envInfo->poly;
            imgContainer->setPixmap(w->envInfo->pmap);
            w->currImg = w->envInfo->currImg;
            imgContainer->currImg = &w->currImg;
            *(imgContainer->regionTmp) = *(w->envInfo->regionTmp);
            w->changeMode(w->envInfo->mode);
            tempObj->setTempature(w->envInfo->tmp);
            imgContainer->refresh();
        }
        else
        {   if(w->env->getEnvironmentLists() -> size() > 0)
            {
                saveStatus(imgContainer,tempObj,parent);
            }
            EnvironmentInfo *newEnv = new EnvironmentInfo();
            QString text = item->text();
            cv::Mat img = tempObj->showImage(text);
            if(!img.size().empty())
            {
                QImage tImg = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_RGB888).rgbSwapped();
                QPixmap tmpPixmap = QPixmap::fromImage(tImg);
                imgContainer->setOrigPicSize(tImg.size());
                imgContainer->setScaleFactor(1.0);
                imgContainer->setPixmap(tmpPixmap);
                imgContainer->setTemp(tempObj->getTempature());
                imgContainer->setPicOffset(QPoint(0,0));
                imgContainer->setPolyOffset(QPoint(0,0));
                imgContainer->setMode(0);
                imgContainer->setPic(tImg);
                imgContainer->regionTmp->clear();
                imgContainer->getTemp().clear();
                imgContainer->setMode(0);
                imgContainer->setEditStatus(false);
                imgContainer->tempPt.clear();
                imgContainer->poly.clear();
                imgContainer->setCenterPos(QPoint(tImg.width() / 2.0,tImg.height() / 2.0));
                //20240808
                imgContainer->setStatus(0);
                imgContainer->setRotateFactor(0);
                newEnv->centerPos = imgContainer->getCenterPos();
                newEnv->rotateFactor = imgContainer->getRotateFactor();
                //
                newEnv->origPicSize = imgContainer->getOrigPicSize();
                newEnv->realPicSize = imgContainer->getOrigPicSize();
                newEnv->scaleFactor = imgContainer->getScaleFactor();
                newEnv->pmap = tmpPixmap;
                newEnv->regionTmp = new std::map<QString,Point*>();
                newEnv->tmp = new std::map<QString,Point*>();
                newEnv->pic = tImg;
                newEnv->imgOffset = imgContainer->getPicOffset();
                newEnv->polyOffset = imgContainer->getPolyOffset();
                newEnv->mode = 0;
                newEnv->isCompleteEdit = false;
                newEnv->tempPt = new std::map<QPoint*,QString>();
                newEnv->poly.clear();
                newEnv->fileName = text;
                newEnv->tMax = tempObj->getTmpDiff().first;
                newEnv->tMin = tempObj->getTmpDiff().second;
                newEnv->currImg = tImg;
                w->currImg = tImg;
                imgContainer->currImg = &w->currImg;
                w->env->newEnvironment(index,newEnv);
                w->envInfo = newEnv;
                imgContainer->refresh();
                //w->envInfo->toString();
                w->selectedIndex = index;
            }
        }

    }
    //w->env->showInfo();
}

double getTempByPixel(ZoomLabel* imgContainer,TempProcess* tempObj)
{
    QPoint pt = imgContainer->getMousePos();
    std::map<QString,Point*> t = tempObj->getTempature();
    if(t.size() <= 0)
        return -100.0;

    double scaleRatio = (double) imgContainer->getOrigPicSize().width() / (double) imgContainer->getRealPicSize().width();
    //裁剪前图形偏移
    QPoint offset = imgContainer->getPicOffset();
    //计算旋转坐标
    QPoint center = imgContainer->getCenterPos();

    double rAng = 360 - imgContainer->getRotateFactor();

    //裁剪后图形偏移
    //相对坐标
    if(imgContainer->poly.empty())
    {
        QPoint rotateCenter = offset + center;
        //QPoint relativePt = (pt  - offset) * scaleRatio;
        QPoint relativePt = pt;
        //旋转坐标，根据二维空间旋转矩阵得到
        //| cos(a) -sin(a)|
        //| sin(a) cos(a) |
        QMatrix transform;
        transform = transform.translate(rotateCenter.x(),rotateCenter.y()).rotate(rAng).translate(-(rotateCenter.x()),-(rotateCenter.y()));
        //QPoint rotatedPt((relativePt.rx() - rotateCenter.rx()) * cos(rAng) - (relativePt.ry() - rotateCenter.ry()) * sin(rAng) + rotateCenter.rx(),(relativePt.rx() - rotateCenter.rx()) * sin(rAng)+ (relativePt.ry() - rotateCenter.ry()) * cos(rAng) + rotateCenter.ry());

        QPoint rotatedPt = transform.map(relativePt);

        relativePt = (relativePt - offset) * scaleRatio;
        QString pos = QString::number(relativePt.x()) + "," + QString::number(relativePt.y());
        if(rAng != 0)
        {
            rotatedPt = (rotatedPt - offset) * scaleRatio;
            pos = QString::number(rotatedPt.x()) + "," + QString::number(rotatedPt.y());
        }

        if(t.find(pos) == t.end()) return -100;
        return t[pos]->temp;
    }
    else
    {
        QMatrix transform;
        QPoint rotateCenter = offset + center;
        transform = transform.translate(rotateCenter.x(),rotateCenter.y()).rotate(rAng).translate(-(rotateCenter.x()),-(rotateCenter.y()));
        QPoint relativePt;
        if(rAng != 0)
        {
            relativePt =  transform.map(pt);
             relativePt = (relativePt  - imgContainer->getPicOffset()) * scaleRatio;
        }
        else
        {
             relativePt = (pt  - imgContainer->getPicOffset()) * scaleRatio;
        }

        //QPoint relativePt = (pt  - imgContainer->getPicOffset());
         QString pos2 = QString::number(relativePt.rx()) + "," + QString::number(relativePt.ry());
         if(imgContainer->regionTmp->find(pos2) == imgContainer->regionTmp->end()) return -100;
         return (*(imgContainer->regionTmp))[pos2]->temp;
    }


}

void exportRegions(ZoomLabel* imgContainer,TempProcess* tempObj,QWidget* parent)
{
    MainWindow *w = (MainWindow*)parent;
    //保存状态
    //保存当前状态
    saveStatus(imgContainer,tempObj,parent);
    QString outputPath = QCoreApplication::applicationFilePath();
    outputPath = outputPath.mid(0,outputPath.lastIndexOf("/"));
    std::map<int,EnvironmentInfo*>* envLists = w->getEnvLists();
    QDir dir(outputPath);
    QDateTime currDate = QDateTime::currentDateTime();
    QString dirName = outputPath + "/" + currDate.toString("yyyyMMddhhmmss") + "Result";
    if (dir.exists())
    {
            dir.mkpath(dirName);
    }
    for(auto file = envLists->begin();file!=envLists->end();file++)
    {
        EnvironmentInfo* envInfo = file->second;
        std::map<QString,Point*> t = *(envInfo->regionTmp);
        QPolygon poly = envInfo->poly;
        std::map<QPoint*,QString> vert = *(envInfo->tempPt);
        QStringList parts = envInfo->fileName.split("/");

        if(poly.empty() || t.size() <= 0)
        {
            QFile outputTempFile(dirName +QString("/") + parts.last());
            //qDebug() <<"writing:" << outputTempFile.fileName() << ","<< envLists->size()<< "\n";
            QTextStream tempStream(&outputTempFile);
            bool ok2 = outputTempFile.open(QIODevice::ReadWrite);
            auto picTmp = envInfo->tmp;
            auto pic = envInfo->pmap;
            for(int y = 0; y < pic.height();y++)
            {
                for(int x=0;x < pic.width();x++)
                {
                    QPoint pt(x,y);
                    pt = pt / envInfo->scaleFactor;
                    QString pos = QString::number(pt.x()) + "," + QString::number(pt.y());
                    if(picTmp->find(pos) != picTmp->end())
                    {
                        tempStream << QString::number((*picTmp)[pos]->temp) << " ";
                    }
                    else
                    {
                        tempStream << envInfo->tMin << " ";
                    }
                }
                tempStream << "\n";
            }
            outputTempFile.flush();
            outputTempFile.close();
            continue;
        }


        QFile outputFile(dirName +QString("/") + parts.last());
        QFile outputPoint(dirName +QString("/") + parts.last().mid(0,parts.last().indexOf(".")) + "-envelope.pts");
        QFile outputVertex(dirName +QString("/") + parts.last().mid(0,parts.last().indexOf(".")) + "-vertex.pts");

        QTextStream fileStream(&outputFile);
        QTextStream pointStream(&outputPoint);
        QTextStream vertexStream(&outputVertex);

        bool ok = outputFile.open(QIODevice::ReadWrite);
        bool ok1 = outputPoint.open(QIODevice::ReadWrite);
        bool ok2 = outputVertex.open(QIODevice::ReadWrite);

        //qDebug() << poly.empty() << "," << (t.size() <= 0) << "," << ok;
        double scaleRatio = (double) envInfo->origPicSize.width() / (double) poly.boundingRect().width();
        double scaleRatio1 = (double) envInfo->origPicSize.height() / (double) poly.boundingRect().height();
        for(int y = 0;y<poly.boundingRect().height() * scaleRatio1;y++)
        {
            for(int x=0;x < poly.boundingRect().width() * scaleRatio;x++)
            {
                QPoint pt(x,y);
                QString pos = QString::number(pt.x()) + "," + QString::number(pt.y());
                if(t.find(pos) != t.end())
                {
                    fileStream << QString::number(t[pos]->temp) << " ";
                }
                else
                {
                    fileStream << envInfo->tMin << " ";
                }
            }
            fileStream << "\n";
        }
        outputFile.flush();
        outputFile.close();
        for(int i =0;i < poly.size();i++)
        {
            pointStream << poly[i].x() <<" " << poly[i].y() << "\n";
        }
        outputPoint.flush();
        outputPoint.close();
        for(auto v : vert)
        {
            vertexStream << v.first->x() << " " << v.first->y() << " " << v.second << "\n";
        }
        outputVertex.flush();
        outputVertex.close();

    }
    QMessageBox::information(parent,"完成","已完成导出");
}

QImage scaledImg(ZoomLabel* imgContainer,TempProcess* tempObj,QWidget* parent)
{
    QImage resultImg;
    try {
        saveStatus(imgContainer,tempObj,parent);
        MainWindow *w = (MainWindow*)parent;
        EnvironmentInfo* envInfo = w->envInfo;
        QPolygon poly = envInfo->poly;
        std::map<QString,Point*> t = *(envInfo->regionTmp);
        QString outputPath = QCoreApplication::applicationFilePath();
        outputPath = outputPath.mid(0,outputPath.lastIndexOf("/"));
        QStringList parts = envInfo->fileName.split("/");
        QFile outputFile(outputPath + QString("/") + "temp.txt");
        if(outputFile.exists())
        {
            outputFile.remove();
        }
        QTextStream fileStream(&outputFile);
        bool ok = outputFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
        double scaleRatio = (double) envInfo->origPicSize.width() / (double) poly.boundingRect().width();
        double scaleRatio1 = (double) envInfo->origPicSize.height() / (double) poly.boundingRect().height();
        double diffVal = tempObj->getTmpDiff().first - tempObj->getTmpDiff().second;
        double currMax = 99999.0;
        double currMin = -99999.0;
        for(int y = 0;y<poly.boundingRect().height() * scaleRatio1;y++)
        {
            for(int x=0;x < poly.boundingRect().width() * scaleRatio;x++)
            {
                QPoint pt(x,y);
                QString pos = QString::number(pt.x()) + "," + QString::number(pt.y());
                if(t.find(pos) != t.end())
                {
                    if(t[pos]->temp > currMax)
                    {
                        currMax = t[pos]->temp;
                    }
                    if(t[pos]->temp < currMin)
                    {
                        currMin = t[pos]->temp;
                    }
                }
            }
        }
        double rate = (currMin - currMax) / (diffVal);
        for(int y = 0;y<poly.boundingRect().height() * scaleRatio1;y++)
        {
            for(int x=0;x < poly.boundingRect().width() * scaleRatio;x++)
            {
                QPoint pt(x,y);
                QString pos = QString::number(pt.x()) + "," + QString::number(pt.y());
                if(t.find(pos) != t.end())
                {
                    fileStream << QString::number(t[pos]->temp) << " ";
                }
                else
                {
                    fileStream << tempObj->getTmpDiff().second   << " ";
                }
            }
            fileStream << "\n";
        }

        for(int x1 = 0;x1 < poly.boundingRect().width() * scaleRatio;x1++)
        {
          if(x1 % 2 == 0)
          {
             fileStream << tempObj->getTmpDiff().first   << " ";
          }
          else
          {
             fileStream << tempObj->getTmpDiff().second   << " ";
          }
        }

        outputFile.flush();
        outputFile.close();
        cv::Mat img = tempObj->showImage(outputPath + QString("/") + "temp.txt");
        resultImg = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_RGB888).rgbSwapped();
    } catch (QException e) {
        qDebug() << e.what();
        QMessageBox::warning(parent,"完成","无法查看图像");
        return resultImg;
    }

   return resultImg;
}

void changeTemp(ZoomLabel* imgContainer,QLineEdit *edit,TempProcess* tempObj,QWidget* parent)
{
    QPoint pt = imgContainer->getMousePos();
    QPoint center = imgContainer->getCenterPos();
    double ratio = (double)(imgContainer->getOrigPicSize().width())/(double)(imgContainer->getRealPicSize().width());
    QPoint offset = imgContainer->getPicOffset();
    double rAng = 360 - imgContainer->getRotateFactor();
    QPoint rotateCenter = offset + center;
    QMatrix transform;
    transform = transform.translate(rotateCenter.x(),rotateCenter.y()).rotate(rAng).translate(-(rotateCenter.x()),-(rotateCenter.y()));

    if(rAng !=0)
    {
        pt = transform.map(pt);
    }
    QPoint relativePt = (pt - offset) * ratio;
    QPoint relativePt1 = (pt - offset);
    QString pos = QString::number(relativePt.x()) + "," + QString::number(relativePt.y());
    std::map<QString,Point*> *temp = new std::map<QString,Point*>();
    *temp = tempObj->getTempature();
    if(temp == nullptr || temp->empty())
    {
        QMessageBox::warning(parent,"警告","无法修改");
        return;
    }
    if(temp->find(pos) != temp->end())
    {
        //qDebug() << edit->toPlainText().toDouble();
        (*temp)[pos]->temp = edit->text().toDouble();
        tempObj->setTempature(temp);
        cv::Mat img = tempObj->getColorRuler();

        QImage tImg = QImage((img.data), img.cols, img.rows, img.step, QImage::Format_RGB888).rgbSwapped();
        QRgb color =  tImg.pixel(relativePt.x(),relativePt.y());
        imgContainer->currImg->setPixel(relativePt.x(),relativePt.y(),color);
        //qDebug() << color << "," << imgContainer->getOrigPicSize() << "," << imgContainer->getRealPicSize();
        //imgContainer->setPixel(pt.x(),pt.y(),color);
        QImage pimg =  imgContainer->getPmap().toImage();
        pimg.setPixel(relativePt1,color);
        imgContainer->setPixmap(QPixmap::fromImage(pimg));
        imgContainer->refresh();
    }
    delete temp;
}

void reloadImg(QListWidget* listWidget, ZoomLabel* imgContainer, QWidget* parent, TempProcess* tempObj)
{
    MainWindow *w = (MainWindow*)parent;
    QListWidgetItem *item = listWidget->currentItem();
    EnvironmentInfo *newEnv = new EnvironmentInfo();

    if(item)
    {
        int index = listWidget->currentRow();
        QString text = item->text();
        cv::Mat img = tempObj->showImage(text);
        if(!img.size().empty())
        {
            QImage tImg = QImage((const unsigned char*)(img.data), img.cols, img.rows, img.step, QImage::Format_RGB888).rgbSwapped();
            QPixmap tmpPixmap = QPixmap::fromImage(tImg);
            imgContainer->setOrigPicSize(tImg.size());
            imgContainer->setScaleFactor(1.0);
            imgContainer->setPixmap(tmpPixmap);
            imgContainer->setTemp(tempObj->getTempature());
            imgContainer->setPicOffset(QPoint(0,0));
            imgContainer->setPolyOffset(QPoint(0,0));
            imgContainer->setMode(0);
            imgContainer->setStatus(0);

            //20240808
            imgContainer->setStatus(0);
            imgContainer->setCenterPos(QPoint(tImg.width() / 2.0,tImg.height() / 2.0));
            imgContainer->setRotateFactor(0);
            imgContainer->regionTmp->clear();
            newEnv->centerPos = imgContainer->getCenterPos();
            newEnv->rotateFactor = imgContainer->getRotateFactor();
            //
            newEnv->origPicSize = imgContainer->getOrigPicSize();
            newEnv->realPicSize = imgContainer->getOrigPicSize();
            newEnv->scaleFactor = imgContainer->getScaleFactor();
            newEnv->pmap = tmpPixmap;
            *(newEnv->regionTmp)=*(imgContainer->regionTmp);
            *(newEnv->tmp) = imgContainer->getTemp();
            newEnv->pic = tImg;
            newEnv->imgOffset = imgContainer->getPicOffset();
            newEnv->polyOffset = imgContainer->getPolyOffset();
            newEnv->mode = imgContainer->getMode();
            newEnv->isCompleteEdit = imgContainer->getEditStatus();
            *(newEnv->tempPt) = imgContainer->tempPt;
            newEnv->poly = imgContainer->poly;
            newEnv->fileName = text;
            newEnv->tMax = tempObj->getTmpDiff().first;
            newEnv->tMin = tempObj->getTmpDiff().second;
            newEnv->currImg = tImg;
            w->env->updateEnvironment(w->selectedIndex,newEnv);
            w->envInfo = newEnv;
            //w->selectedIndex = index;
            w->currImg = tImg;
            *(imgContainer->currImg) = tImg;
            imgContainer->refresh();
            //w->envInfo->toString();
        }

    }

}

void changeStatus(QPushButton* btn, ZoomLabel* imgContainer,QWidget* parent)
{
    MainWindow *w = (MainWindow *)parent;
    int s = 0;
    if(w->getStatus().first == 0)
    {
        s = 1;
    }

    w->setStatus(s);
    imgContainer->setStatus(s);
    btn->setText(w->getStatus().second);
}
#endif // BEHEAVIOR_H
